import { Messages } from "../../constants/Messages";

const { ccclass, property, executeInEditMode } = cc._decorator;

@ccclass
@executeInEditMode
export class BoxRadius extends cc.Component {

    @property
    _ratioX: number = .5;
    @property({ type: cc.Float, min: 0, max: 1, step: .01 })
    get ratioX() {
        return this._ratioX;
    }
    set ratioX(val: number) {
        if (val > .5) {
            this._ratioX = val / this.node.width;
        } else {
            this._ratioX = val;
        }
        this.onUpdateMat();
    }
    @property
    _ratioY: number = .5;
    @property({ type: cc.Float, min: 0, max: 1, step: .01 })
    get ratioY() {
        return this._ratioY;
    }
    set ratioY(val: number) {
        if (val > .5) {
            this._ratioY = val / this.node.height;
        } else {
            this._ratioY = val;
        }
        this.onUpdateMat();
    }

    @property
    useOutline: boolean = false;
    @property
    _outlineColor: cc.Color = cc.Color.WHITE;
    @property({ type: cc.Color, visible: function () { return this.useOutline } })
    get outlineColor() {
        return this._outlineColor;
    }
    set outlineColor(val: cc.Color) {
        this._outlineColor = val;
        this.onUpdateMat();
    }
    @property
    _outlineWidth: number = 1;
    @property({ type: cc.Integer, visible: function () { return this.useOutline } })
    get outlineWidth() {
        return this._outlineWidth;
    }
    set outlineWidth(val: number) {
        this._outlineWidth = val;
        this.onUpdateMat();
    }

    _mat: cc.Material = null;

    onLoad() {
        this.node.on(Messages.Nodes.BoxRadiusChangeRatio, this.setRadiusRatio, this);
        this.node.on(Messages.Nodes.BoxRadiusChangeSize, this.setRadiusSize, this);
    }

    start() {
        if (!this._mat) this._mat = this.node.getComponent(cc.Sprite).getMaterial(0);
        this.onUpdateMat();
    }

    setRadiusRatio(x?: number, y?: number) {
        x != null && (this._ratioX = x);
        y != null && (this._ratioY = y);
        this.onUpdateMat();
    }

    setRadiusSize(x?: number, y?: number) {
        x != null && (this._ratioX = x / this.node.width);
        y != null && (this._ratioY = y / this.node.height);
        this.onUpdateMat();
    }

    onUpdateMat() {
        if (!this._mat) this._mat = this.node.getComponent(cc.Sprite).getMaterial(0);
        const mat = this._mat;
        const width = this.node.width, height = this.node.height;
        const dis = cc.v2(width * this.ratioX, height * this.ratioY);
        mat.setProperty("size", cc.v2(width, height));
        mat.setProperty("leftTop", dis);
        mat.setProperty("leftBottom", dis);
        mat.setProperty("rightTop", dis);
        mat.setProperty("rightBottom", dis);

        let frame = this.node.getComponent(cc.Sprite).spriteFrame;
        let l = 0, r = 0, b = 1, t = 1;
        // @ts-ignore
        l = frame.uv[0], t = frame.uv[5], r = frame.uv[6], b = frame.uv[3];
        let u_uvOffset = new cc.Vec4(l, t, r, b);
        let u_uvRotated = frame.isRotated() ? 1.0 : 0.0;
        mat.setProperty("u_uvOffset", u_uvOffset);
        mat.setProperty("u_uvRotated", u_uvRotated);

        mat.define("USE_OUTLINE", this.useOutline);
        if (this.useOutline) {
            mat.setProperty("outlineColor", this.outlineColor);
            mat.setProperty("outlineWidth", this.outlineWidth);
        }
    }
}

